Skip to main content
Version: 26.2.0

Adding Conditional Formatting

Conditional color formatting allows you to dynamically change the color of chart elements based on their data values. By applying different colors based on conditions, you can highlight important data points, show performance levels, or make your visualizations more intuitive and informative.

Simple Threshold-Based Coloring

Apply different colors based on whether values meet a condition:

/**
 * Available Columns:
 * "Ship Mode"
 * "Total Discount"
 */

const { muze, getDataFromSearchQuery } = viz;
  
const data = getDataFromSearchQuery();

muze.canvas()
    .rows(["Total Discount"])
    .columns(["Ship Mode"])
    .layers([{
        mark: "bar",
        encoding: {
            color: {
                value: (rowData) => {
                    if (rowData.datum.y < 150) {
                        return "red";
                    } else {
                        return "blue";
                    }
                }
            }
        }
    }]) 
    .data(data)
    .mount("#chart");
/**
 * Available Columns:
 * "Ship Mode"
 * "Total Discount"
 * "Total Quantity"
 * "Measure names" // If 'measureValues' is enabled.
 * "Measure values" // If 'measureValues' is enabled.
 */

const {
    muze,
    getDataFromSearchQuery
} = viz;

const data = getDataFromSearchQuery({
    measureValues: {
        enabled: true
    }
});

muze.canvas()
    .rows(["Ship Mode"])
    .columns(["Measure names"])
    .layers([{
        mark: "text",
        encoding: {
            text: "Measure values",
            color: {
                value: (rowData) => {
                    if (rowData.datum.y === "truck") {
                        return "red";
                    } else {
                        return "blue";
                    }
                }
            }
        }
    }])
    .data(data)
    .mount("#chart");

Understanding rowData

The rowData object passed to your conditional function contains:

PropertyDescriptionExample
datum.xX-axis value"Express Air"
datum.yY-axis value125000

Category-Based Coloring

Apply colors based on category values rather than numeric thresholds:

/**
 * Available Columns:
 * "Ship Mode"
 * "Total Discount"
 */
 
const { muze, getDataFromSearchQuery } = viz;
  
const data = getDataFromSearchQuery();

muze.canvas()
    .rows(["Total Discount"])
    .columns(["Ship Mode"])
    .layers([{
        mark: "bar",
        encoding: {
            color: {
                value: (rowData) => {
                    const shipMode = rowData.datum.x;                 
                    if (shipMode === "air") {
                        return "red";
                    } else {
                        return "blue"; 
                    }
                }
            }
        }
    }]) 
    .data(data)
    .mount("#chart");

Adding a reference line with conditional formatting

Reference lines are horizontal or vertical lines that mark important thresholds, targets, or benchmarks on your charts. When combined with conditional formatting, they create powerful visualizations that instantly communicate whether values meet specific criteria.

/**
 * Available Columns:
 * "Ship Mode"
 * "Total Discount"
 * --- END --- 
 */

const {
    muze,
    getDataFromSearchQuery
} = viz;
  
const data = getDataFromSearchQuery();

muze.canvas()
.rows(["Total Discount"])
.columns(["Ship Mode"])
.layers([
    {
        mark: "bar",
        encoding: {
            x: "Ship Mode",
            y: "Total Discount",
            color: {
                value: (rowData) => {
                    if (rowData.datum.y < 100) {
                        return "red";
                    } else {
                        return "blue";
                    }
                }
            }
        }
    },
    {
      mark: "tick",
      encoding: {
        x: {
          field: null,
        },
        y: "Total Discount",
        color: {
          value: () => "green",
        },
      },
      source: () => {
        const constData = [{ "Total Discount": 100 }];
        const constSchema = [
          {
            name: "Total Discount",
            type: "measure",
          },
        ];
        const parsedData = muze.DataModel.loadDataSync(
          constData,
          constSchema,
        );
        return new muze.DataStore(parsedData);
      },
      
    },
])
.data(data)
.mount("#chart");

Adding reference bands with conditional Formatting

Reference bands are horizontal or vertical bars that highlight specific ranges or thresholds on your charts. Unlike reference lines which mark a single value, reference bands show a range between two values.

/**
 * Available Columns:
 * "Ship Mode"
 * "Total Discount"
 * --- END --- 
 */

const {
    muze,
    getDataFromSearchQuery,
} = viz;
  
const data = getDataFromSearchQuery();
const ds = new muze.DataStore(data)
  .calculateVariable(
    { name: "Discount_start", type: "measure" },
    ["Total Discount"],
    () => null,
  )
  .calculateVariable(
    { name: "Discount_end", type: "measure" },
    ["Total Discount"],
    () => null,
  );

muze.canvas()
.rows([muze.Operators.share("Total Discount", "Discount_start", "Discount_end")])
.columns(["Ship Mode"])
.layers([
    {
        mark: "bar",
        encoding: {
          x: { field: null },
          y: "Discount_start",
          y0: "Discount_end",
          color: {
            value: () => "green",
          },
        },
        source: () => {
          const barData = [{ Discount_start: 3000, Discount_end: 3500 }];
          const barSchema = [
            { name: "Discount_start", type: "measure", subtype: "continuous" },
            { name: "Discount_end", type: "measure", subtype: "continuous" },
          ];
          const parsedData = muze.DataModel.loadDataSync(
            barData,
            barSchema,
          );
          const ds = new muze.DataStore(parsedData);
          return ds;
        },
      },
    {
        mark: "bar",
        encoding: {
            x: "Ship Mode",
            y: "Total Discount"
        }
    },
])
.config({
    axes: {
        y: {
            name: "Total Discount"
        }
    }
})
.data(ds)
.mount("#chart");

Why Do We Add Placeholder Columns?

Reference bands require placeholder calculated variables to enable axis sharing between your data layer and the band layer. These placeholder columns:

Names can be anything - "Discount_start", "Band_Upper", or any name you choose

Values can be anything - We typically use () => null, but any value works

Are never displayed on the chart - They're just placeholders

Enable axis sharing - They allow the band to use the same Y-axis scale as your data

// These placeholder columns with null values
const ds = new muze.DataStore(data)
    .calculateVariable({ name: "Discount_start", type: "measure" }, ["Total Discount"], () => null)
    .calculateVariable({ name: "Discount_end", type: "measure" }, ["Total Discount"], () => null);

// Allow this axis sharing
.rows([muze.Operators.share("Total Discount", "Discount_start", "Discount_end")])

The actual band boundary values (e.g., 3000 and 3500) come from the source() function in the band layer, not from these placeholder columns.